package iscript.gameFramework.NetService 
{
	import flash.display.DisplayObject;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.utils.ByteArray;
	import be.boulevart.as3.security.RC4;
	import flash.utils.Dictionary;
	import flash.utils.Endian;
	import iscript.coreFramework.debug.ArthropodDebug;
	import iscript.gameFramework.NetService.core.ServerEntity;
	import iscript.gameFramework.NetService.core.ServiceEvent;
	import iscript.gameFramework.NetService.data.KeyTable;
	import iscript.gameFramework.NetService.data.NetMessageBase;
	import iscript.gameFramework.NetService.data.BufferList;
	import iscript.gameFramework.NetService.data.WatchServiceEventList;
	import iscript.gameFramework.NetService.data.WatchServiceItem;
	
	
	
    //TODO: watchService 修改成 override addEventListener  
	//BUG:  watchService 修改成 override addEventListener
	
		
	public class ServiceProxy extends EventDispatcher
	{
		static public const ConnectSuccess:String = "ConnectSuccess";
		static public const ERROR:String = "ERROR";
		static public const CLOSE:String = "CLOSE";
		
		public function ServiceProxy()
		{
		 
		}
		
		static private var _server:ServerEntity = new ServerEntity();
		static public var  instance:ServiceProxy = new ServiceProxy();
		public var Concurrent:int = 2;		
		public var encrypt:Boolean = false;
		
		/**
		 * QQ平台 TGW数据包
		 */
		public var TGWPackData:String;
		

		/**
		 * 	_commandList[NetCommand.GO_SETUP_BUILD_ACK] = AddBuildCheck;
		 * @param	data
		 */
		
		public function registerCommandList(data:Dictionary):void {
			 BufferList.getInstance().loadCommandList(data);
			}
			
		//public function reisterKeyTable(data:String):void {
		//	KeyTable.createInstance(data:String);
		//	}
		
		public function connect(ip:String, port:int,frameTarget:DisplayObject):void {
			_server.addEventListener(ServiceProxy.ConnectSuccess, function(e:Event):void {
				instance.dispatchEvent(e);
				})  
			_server.connect(ip, port);	
			if(frameTarget!=null)setBufferThread(frameTarget);
		}
			
		private var _watchServiceEventList:WatchServiceEventList = new WatchServiceEventList();
		
		public function hasWatchService(commandName:String):Boolean {
			    return _watchServiceEventList.isRegisterBycommandName(commandName); 
			}
         
		public function get watchServiceEventPool():WatchServiceEventList {
			     return _watchServiceEventList;
			}
		
		/**
		 * 监听服务器信息
		 * @param	commandName
		 * @param	callback
		 */	
		public function watchService(commandName:String, callback:Function):void {
			      _watchServiceLogic(commandName, callback, false);			   
			 }
			
		private function _watchServiceLogic(commandName:String, callback:Function,autoremove:Boolean):void {
			      var processFn:Function = function(e:ServiceEvent):void {
													var  message:NetMessageBase =  ServiceEvent(e).Message;
													if (ServiceEvent(e).commandName == commandName) {
														trace("接受对应的socket:" + commandName);
													     callback(message);
														if(autoremove){removeWatchService(commandName,callback)}
														}
												    };			     
			      _watchServiceEventList.add(commandName, callback, processFn);	      
			      instance.addEventListener(ServiceEvent.GETPACKDATA,processFn);   
			 }	
			
		public function removeWatchService(commandName:String, callback:Function):void {
			     var list:Vector.<WatchServiceItem> = _watchServiceEventList.getWatchServiceItem(commandName,callback);
				 for each( var item:WatchServiceItem  in list) {
					instance.removeEventListener(ServiceEvent.GETPACKDATA, item.processFn);
				 }
				 _watchServiceEventList.remove(commandName, callback);
		}	
		
		public function watchOnceService(commandName:String, callback:Function):void{
			     _watchServiceLogic(commandName, callback,true);
			}
			
			
		
		/**
		 * 设置每帧派发信息条数
		 * @param	stage
		 * @param	count
		 */
		public function setBufferThread(root:DisplayObject, count:Number = 2):void {
			   Concurrent = count;
			   root.removeEventListener(Event.ENTER_FRAME, _bufferHandler);
			   root.addEventListener(Event.ENTER_FRAME, _bufferHandler);
			}
			
		private function _bufferHandler(e:Event):void {
				if (_server.connected && BufferList.getInstance().hasBuffer()) {
					 for (var i:int = 0; i <Concurrent; i++) 
					 {
						 BufferList.getInstance().sendOnce();
					 }
				  }
			}
			
			
		public function close():void {
			_server.close();
			}	
		
			
		public function send(commandName:String, data:ByteArrayCollection=null):void {		
			trace("发送对应的socket:" + commandName);
			var packId:Array = commandName.split("-");
			var _mainId:int = packId[0];
			var _childId:int = packId[1];
			
			var bodyData:ByteArrayCollection = data;
			if (data == null) bodyData = ByteArrayCollection.Empty;

			     
			var index:int = KeyTable.getInstance().randomIndex();
			var keyString:String = KeyTable.getInstance().content[index];
			
			var mainData:ByteArrayCollection = new ByteArrayCollection();
			    mainData.toByte(index);
				mainData.toWord(7 + bodyData.result.length)
					 
				 
			var headData:ByteArrayCollection = new ByteArrayCollection();
			    headData.toWord(_mainId);
				headData.toWord(_childId);
			
 
			var EncryptData:ByteArray = new ByteArray();
			    EncryptData.writeBytes(headData.result);
				EncryptData.writeBytes(bodyData.result);
				if (ServiceProxy.instance.encrypt) {
					EncryptData = RC4.encryptByte(EncryptData, keyString);
					}
			
			var  serverData:ByteArray = new ByteArray();
			     serverData.writeBytes(mainData.result);
				 serverData.writeBytes(EncryptData);
				 if(data==null){ ArthropodDebug.log("NULLSEND:"+_mainId + "-" + _childId, ArthropodDebug.RED);}
				 _server.send(serverData);
			     
				 
			// ArthropodDebug.log("SEND:"+_mainId + "-" + _childId, ArthropodDebug.RED);
				 
			}
		 
			
	}

}
